﻿using System;
using System.Collections.Generic;
using CID.Execution.Support.Information;

namespace CID.Execution.Support.PackageHandling
{
    public sealed class PackageHandlerFactory
    {
        public static readonly PackageHandlerFactory Instance = new PackageHandlerFactory();

        private Dictionary<string, Type> packageHandlerTypesMap;
        
        private PackageHandlerFactory()
        {
            packageHandlerTypesMap = new Dictionary<string, Type>();
        }

        public IPackageHandler CreatePackageHandler(PackageTypeInfo packageType) 
        {
            if (!packageHandlerTypesMap.ContainsKey(packageType.Name))
                throw new PackageHandlerNotFoundException(packageType);

            return (IPackageHandler) Activator.CreateInstance(packageHandlerTypesMap[packageType.Name]);
        }

        public void RegisterPackageHandlerType(string packageTypeName, Type packageHandlerType)
        {
            if (!typeof(IPackageHandler).IsAssignableFrom(packageHandlerType))
                throw new InvalidCastException(String.Format("Type {0} is not a valid IPackageHandler", packageHandlerType));
            if (packageHandlerType.IsAbstract || (packageHandlerType.GetConstructor(new Type[0]) == null))
                throw new InvalidCastException(String.Format("Type {0} can't be instantiated with a parameterless constructor", packageHandlerType));

            if (!packageHandlerTypesMap.ContainsKey(packageTypeName))
                packageHandlerTypesMap.Add(packageTypeName, null);

            packageHandlerTypesMap[packageTypeName] = packageHandlerType;
        }

        public void UnregisterPackageHandlerType(string packageTypeName)
        {
            if (packageHandlerTypesMap.ContainsKey(packageTypeName))
                packageHandlerTypesMap.Remove(packageTypeName);
        }
    }
}
